package com.mioto.ld.module.statistics;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.mioto.ld.module.device.dao.DeviceAlertLogDao;
import com.mioto.ld.module.device.dao.DeviceDao;
import com.mioto.ld.module.device.dao.DevicePressTimeLogDao;
import com.mioto.ld.module.device.model.DeviceAlertCounterStatisticsVO;
import com.mioto.ld.module.statistics.model.AppAlertStatisticVO;
import com.mioto.ld.module.statistics.model.*;
import com.mioto.ld.utils.SpringBeanUtil;
import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author mioto-qinxj
 * @date 2024/6/16
 * @desc 设备销量统计
 */
@Slf4j
public abstract class AbstractStatistics {
    private DevicePressTimeLogDao devicePressTimeLogDao;
    private DeviceDao deviceDao;

    private DeviceAlertLogDao deviceAlertLogDao;
    protected int index;



    protected AbstractStatistics(){

    }

    /**
     * 设备销量统计
     * @param searchDTO
     * @return
     */
    public DeviceSaleStatisticsVO deviceSaleStatistics(DeviceSaleSearchDTO searchDTO){
        calSearchDate(searchDTO);
        DeviceSaleStatisticsVO deviceSaleStatistics = new DeviceSaleStatisticsVO();
        deviceSaleStatistics.setProductStatistics(getDeviceDao().saleProductStatistics(searchDTO));
        deviceSaleStatistics.setAreaStatistics(getDeviceDao().saleAreaStatistics(searchDTO));
        List<SameCompareStatisticsVO> sameCompareStatistics = getDeviceDao().saleSameCompareStatistics(searchDTO);
        deviceSaleStatistics.setSameCompareStatistics(buildSameCompareStatistics(sameCompareStatistics,searchDTO));
        return deviceSaleStatistics;
    }

    /**
     * 材料销量统计
     * @param searchDTO
     * @return
     */
    public MaterialSaleStatisticsVO materialSaleStatistics(MaterialSaleSearchDTO searchDTO){
        calSearchDate(searchDTO);
        MaterialSaleStatisticsVO material = getDevicePressTimeLogDao().saleCounterStatistics(searchDTO);
        material.setAreaStatistics(getDevicePressTimeLogDao().saleAreaStatistics(searchDTO));
        List<SameCompareStatisticsVO> sameCompareStatistics = getDevicePressTimeLogDao().saleSameCompareStatistics(searchDTO);
        material.setSameCompareStatistics(buildSameCompareStatistics(sameCompareStatistics,searchDTO));
        return material;
    }

    /**
     * 设备故障统计
     * @param searchDTO
     * @return
     */
    public DeviceFaultStatisticsVO faultStatistics(DeviceFaultSearchDTO searchDTO){
        calSearchDate(searchDTO);
        DeviceFaultStatisticsVO deviceFault = new DeviceFaultStatisticsVO();
        deviceFault.setDeviceFaultTypeStatistics(getDeviceDao().faultTypeStatistics(searchDTO));
        deviceFault.setAreaStatistics(getDeviceDao().faultAreaStatistics(searchDTO));
        List<SameCompareStatisticsVO> sameCompareStatistics = getDeviceDao().faultSameCompareStatistics(searchDTO);
        deviceFault.setSameCompareStatistics(buildSameCompareStatistics(sameCompareStatistics,searchDTO));
        return deviceFault;
    }

    /**
     * app设备告警统计
     * @param searchDTO
     * @return
     */
    public AppAlertStatisticVO appAlertStatistics(AppStatisticSearchDTO searchDTO){
        log.info("app设备告警统计");
        calSearchDate(searchDTO);
        AppAlertStatisticVO appAlertStatisticVO = getDeviceAlertLogDao().mainCounterStatistic(searchDTO);
        List<DeviceAlertCounterStatisticsVO> counterStatistics = getDeviceAlertLogDao().appCounterStatistics(searchDTO);
        if (CollUtil.isNotEmpty(counterStatistics)){
            counterStatistics = (List<DeviceAlertCounterStatisticsVO>) StatisticsUtil.reBuild(counterStatistics,buildTempArray(searchDTO.getStartTime(),0),index);
        }
        appAlertStatisticVO.setAlertCounterStatistics(counterStatistics);
        appAlertStatisticVO.setDeviceFaultTypeStatistics(getDeviceDao().appFaultTypeStatistics(searchDTO));
        return appAlertStatisticVO;
    }

    /**
     * app设备销量统计
     * @param searchDTO
     * @return
     */
    public AppDeviceSaleStatisticsVO appDeviceSaleStatistics(AppStatisticSearchDTO searchDTO){
        log.info("app设备销量统计");
        calSearchDate(searchDTO);
        AppDeviceSaleStatisticsVO deviceSaleStatistics = getDeviceDao().mainCounterStatistic(searchDTO);
        deviceSaleStatistics.setAreaStatistics(getDeviceDao().saleAreaStatistics(searchDTO));
        List<StatisticsPO> statistics = getDeviceDao().appSaleStatistics(searchDTO);
        if (CollUtil.isNotEmpty(statistics)){
            statistics = (List<StatisticsPO>) StatisticsUtil.reBuild(statistics,buildTempArray(searchDTO.getStartTime(),0),index);
        }
        deviceSaleStatistics.setStatistics(statistics);
        return deviceSaleStatistics;
    }

    /**
     * app材料销量统计
     * @param searchDTO
     * @return
     */
   public AppMaterialSaleStatisticsVO appMaterialSaleStatistics(MaterialSaleSearchDTO searchDTO){
       calSearchDate(searchDTO);
       MaterialSaleStatisticsVO material = getDevicePressTimeLogDao().saleCounterStatistics(searchDTO);
       material.setAreaStatistics(getDevicePressTimeLogDao().saleAreaStatistics(searchDTO));
       AppMaterialSaleStatisticsVO appMaterialSaleStatisticsVO = new AppMaterialSaleStatisticsVO();
       BeanUtil.copyProperties(material, appMaterialSaleStatisticsVO, "sameCompareStatistics");
       List<StatisticsPO> statistics = getDevicePressTimeLogDao().appSaleStatistics(searchDTO);
       if (CollUtil.isNotEmpty(statistics)){
           statistics = (List<StatisticsPO>) StatisticsUtil.reBuild(statistics,buildTempArray(searchDTO.getStartTime(),0),index);
       }
       appMaterialSaleStatisticsVO.setStatistics(statistics);
       return appMaterialSaleStatisticsVO;
    }

    private List<SameCompareStatisticsVO> buildSameCompareStatistics(List<SameCompareStatisticsVO> sameCompareStatistics,SearchConditionDTO searchDTO){
        List<SameCompareStatisticsVO> newList = new ArrayList<>(0);
        if (CollUtil.isNotEmpty(sameCompareStatistics)){
            SameCompareStatisticsVO[] array = buildTempArray(searchDTO.getStartTime(),1);
            List<SameCompareStatisticsVO> list = sameCompareStatistics.stream()
                    .filter(obj-> obj.getType() == 1)
                    .collect(Collectors.toList());
            newList.addAll((List<SameCompareStatisticsVO>) StatisticsUtil.reBuild(list,array,index));
            array = buildTempArray(searchDTO.getSameCompareStartDate(),2);
            list = sameCompareStatistics.stream()
                    .filter(obj-> obj.getType() == 2)
                    .collect(Collectors.toList());
            newList.addAll((List<SameCompareStatisticsVO>) StatisticsUtil.reBuild(list,array,index));
        }
        return newList;
    }

    protected SameCompareStatisticsVO[] buildTempArray(Date startDate,int type){
        SameCompareStatisticsVO[] array = new SameCompareStatisticsVO[index];
        DateTime dateTime;
        for (int i = 0; i < index; i++) {
            dateTime = DateUtil.offsetDay(startDate,i);
            array[i] = new SameCompareStatisticsVO();
            array[i].setTime(buildTimeStr(startDate,i));
            array[i].setType(type);
            array[i].setFormatDate(DateUtil.format(dateTime, DatePattern.NORM_DATE_PATTERN));
        }
        return array;
    }
    protected String buildTimeStr(Date startDate,int index) {
        DateTime dateTime = DateUtil.offsetDay(startDate,index);
        int num = dateTime.dayOfMonth();
        if (num < 10){
            return "0" + num;
        }
        return num + "";
    }

    private DeviceDao getDeviceDao(){
        if (ObjectUtil.isNull(deviceDao)){
            deviceDao = SpringBeanUtil.getBean(DeviceDao.class);
        }
        return deviceDao;
    }
    private DevicePressTimeLogDao getDevicePressTimeLogDao(){
        if (ObjectUtil.isNull(devicePressTimeLogDao)){
            devicePressTimeLogDao = SpringBeanUtil.getBean(DevicePressTimeLogDao.class);
        }
        return devicePressTimeLogDao;
    }

    private DeviceAlertLogDao getDeviceAlertLogDao(){
        if (ObjectUtil.isNull(deviceAlertLogDao)){
            deviceAlertLogDao = SpringBeanUtil.getBean(DeviceAlertLogDao.class);
        }
        return deviceAlertLogDao;
    }
    /**
     * 计算日期查询条件
     * @param searchDTO
     */
    protected abstract void calSearchDate(SearchConditionDTO searchDTO);
}
